﻿using Celeriq.Common;
using Celeriq.DataCore.EFDAL;
using Celeriq.DataCore.EFDAL.Entity;
using Celeriq.Utilities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Celeriq.RepositoryAPI
{
    internal class DimensionCache
    {
        private int _repositoryId;
        private Guid _repositoryKey;
        private long _lastDIdx = 0;
        private const long FIRST_DIDX = 1000000;

        public DimensionCache(int repositoryId, Guid repositoryKey, DimensionDefinition dimensionDefinition)
        {
            _repositoryId = repositoryId;
            _repositoryKey = repositoryKey;
            this.DimensionDefinition = dimensionDefinition;
            this.RefinementList = new List<RefinementItem>();
        }

        private static DataCore.EFDAL.Entity.DimensionStore CreateDimension(int repositoryId, Guid repositoryKey, DataCoreEntities context, DimensionDefinition dimensionDefinition)
        {
            try
            {
                var dItem = context.DimensionStore.FirstOrDefault(x => x.RepositoryDefinition.UniqueKey == repositoryKey && x.DIdx == dimensionDefinition.DIdx);
                if (dItem == null)
                {
                    dItem = new DataCore.EFDAL.Entity.DimensionStore();
                    dItem.RepositoryId = repositoryId;
                    dItem.DIdx = dimensionDefinition.DIdx;
                    dItem.Name = dimensionDefinition.Name;
                    context.AddItem(dItem);
                    context.SaveChanges();
                }
                return dItem;
            }
            catch (Exception ex)
            {
                Logger.LogError(ex);
                throw;
            }
        }

        //public static DimensionCache Load(int repositoryId, Guid repositoryKey, DimensionDefinition dimensionDefinition)
        //{
        //    try
        //    {
        //        using (var context = new DataCoreEntities())
        //        {
        //            var retval = new DimensionCache(repositoryId, repositoryKey, dimensionDefinition);
        //            var item = context.DimensionStore.FirstOrDefault(x => x.RepositoryId == 0 && x.DIdx == dimensionDefinition.DIdx);
        //            if (item == null) item = CreateDimension(repositoryId, repositoryKey, context, dimensionDefinition);

        //            foreach( var data in  item.DimensionDataList)
        //            {
        //                var r = data.Data.BinToObject<RefinementItem>();
        //                retval.RefinementList.Add(r);
        //            }

        //            return retval;
        //        }
        //    }
        //    catch (Exception ex)
        //    {
        //        Logger.LogError(ex);
        //        throw;
        //    }
        //}

        public List<RefinementItem> RefinementList { get; private set; }

        public DimensionDefinition DimensionDefinition { get; private set; }

        public void Initialize(List<Celeriq.DataCore.EFDAL.Entity.DimensionStore> dbDimensions)
        {
            try
            {
                var item = dbDimensions.FirstOrDefault(x => x.DIdx == this.DimensionDefinition.DIdx);
                if (item == null) return;

                foreach (var data in item.DimensionDataList)
                {
                    this.RefinementList.Add(data.Data.BinToObject<RefinementItem>());
                }
            }
            catch (Exception ex)
            {
                Logger.LogError(ex);
                throw;
            }
        }

        public void WriteItem(RefinementItem refinementItem)
        {
            try
            {
                using (var context = new DataCoreEntities())
                {
                    var item = context.DimensionStore.FirstOrDefault(x => x.RepositoryDefinition.UniqueKey == _repositoryKey && x.DIdx == this.DimensionDefinition.DIdx);
                    if (item == null) item = CreateDimension(_repositoryId, _repositoryKey, context, this.DimensionDefinition);

                    context.AddItem(new DimensionData
                    {
                        Data = refinementItem.ObjectToBin(),
                        DimensionsionStoreId = item.DimensionStoreId,
                    });
                    context.SaveChanges();
                }
            }
            catch (Exception ex)
            {
                Logger.LogError(ex);
                throw;
            }
        }

    }
}
